<script>
import { arrayUnique } from '@/utils'
import { authKey } from '@/config/authKey'
import { formatMenusCode } from '@/utils/menu'
import './index.scss'

export default {
  name: 'AuthTree',
  props: {
    rightStr: { // 后台返回的数据权限
      type: String,
      default: ''
    },
    isAdmin: { // 是否具有所有权限
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      authKeyList: [], // 配置的 authKey
      rightList: []
    }
  },
  created() {
    this.rightList = this.rightStr ? this.rightStr.split(',') : []
    this.authKeyList = formatMenusCode(authKey, this.isAdmin)
    if (!this.isAdmin) {
      this._setAuthKeyList()
    } else {
      this.rightList = this._getCodeAll(this.authKeyList)
    }
  },
  methods: {
    handleChange(e, item) { // 权限勾选
      const isChecked = e
      const newRightList = arrayUnique([
        ...(isChecked ? this._getParentsCode(item.code) : []),
        ...this._getChildrenCode(item)
      ])
      isChecked && (this.rightList = [...this.rightList, ...newRightList])
      !isChecked && (this.rightList = this.rightList.filter(e => !newRightList.includes(e)))
      this._setAuthKeyList()
    },

    _getCodeAll(authList) { // 获取所有的 code
      const codeAll = []
      const mapAuthList = (list) => {
        list.map(item => {
          codeAll.push(item.code)
          item.children && mapAuthList(item.children)
        })
      }
      mapAuthList(authList)
      return codeAll
    },

    _setAuthKeyList() { // 设置 authKey
      this.authKeyList = this._formatMenusStatus(this.authKeyList, this.rightList)
    },

    _formatMenusStatus(menuList, rightList = []) { // 格式化选中权限
      const newMenuList = JSON.parse(JSON.stringify(menuList))
      const mapMenuList = list => {
        list.map(item => {
          if (rightList.includes(item.code)) {
            item.status = true
          } else {
            item.status = false
          }
          item.children && mapMenuList(item.children)
        })
      }
      mapMenuList(newMenuList)
      return newMenuList
    },

    _getChildrenCode(menuObj) { // 获取 children 的 code
      const menuCodeList = []
      const mapMenuObj = (menuObj, isFirst = true) => {
        menuObj.code && isFirst && menuCodeList.push(menuObj.code)
        menuObj.children &&
                menuObj.children.map(menu => {
                  menuCodeList.push(menu.code)
                  menu.children && mapMenuObj(menu, false)
                })
      }
      mapMenuObj(menuObj)
      return menuCodeList
    },

    _getParentsCode(code) { // 获取 父级 的 code
      if (!code.includes('_')) return code
      const code1 = code.split('_')[0]
      const code2 = code.substring(0, code.lastIndexOf('_'))
      return [code1, code2, code]
    },

    authTreeNode(list) { // 权限树
      return list.map(menu => (
        <div class='card' key={menu.code}>
          <div class='header'>
            <div class='title' class={ menu.status ? 'selected' : '' }>{menu.name}</div>
            <el-switch value={menu.status} onChange={e => this.handleChange(e, menu)} />
          </div>
          {
            menu.children && (
              <div class='content'>
                { !menu.children[0].type
                  ? this.secondMenuNode(menu.children)
                  : <div class='item'>
                    {this.btnNode(menu.children)}
                  </div>
                }
              </div>
            )
          }
        </div>
      ))
    },

    secondMenuNode(menus) { // 二级菜单
      return menus.map(menu => (
        <div class='item' key={menu.code}>
          <div class='subheade'>
            <el-checkbox value={menu.status} onChange={e => this.handleChange(e, menu)}>{menu.name}</el-checkbox>
          </div>
          { menu.children && this.btnNode(menu.children) }
        </div>
      ))
    },

    btnNode(btns) { // 按钮
      return (
        <ul class='btn-list'>
          {
            btns.map(btn => (
              <li key={btn.code}>
                <el-checkbox value={btn.status} onChange={e => this.handleChange(e, btn)}>{btn.name}</el-checkbox>
              </li>
            ))
          }
        </ul>
      )
    }
  },

  render(h) {
    const { authTreeNode, authKeyList } = this

    return (
      <div class='auth-tree'>
        {authTreeNode(authKeyList)}
      </div>
    )
  }
}
</script>
